<template>
  <fullscreen :fullscreen.sync="fullscreen" class="container">
    <!-- <div class="container"> -->
    <div
      @click="toggle"
      :class="['btn', { back: fullscreen, screen: !fullscreen }]"
    ></div>
    <div class="header">
      <div class="left-header">
        <img src="@/assets/images/exhibition/logo.png" alt="" />
        <img src="@/assets/images/exhibition/split.png" alt="" />
      </div>
      <div class="right-header">
        <div class="area">{{ areaName }}</div>
        <div class="time">
          <div>{{ timeObj.year }}</div>
          <div>{{ timeObj.date }}</div>
          <div>{{ timeObj.time }}</div>
        </div>
        <img src="@/assets/images/exhibition/header.png" alt="" />
      </div>
    </div>
    <div id="preview-map" class="preview-map-container">地图加载中...</div>
    <div class="left-panel">
      <div
        class="left-panel-item"
        v-for="(item, key, index) in leftPanelData"
        :key="index"
      >
        <div>{{ item.label }}</div>
        <div>
          <span class="left-panel-value">{{ item.value }}</span
          ><span>{{ item.unit }}</span>
        </div>
      </div>
    </div>
    <div class="right-panel">
      <div class="right-panel-number">
        <div
          class="right-panel-item"
          v-for="(item, key, index) in rightPanelData"
          :key="index"
        >
          <div>
            <span class="right-panel-value">{{ item.value }}</span
            ><span>{{ item.unit }}</span>
          </div>
          <div>{{ item.label }}</div>
        </div>
      </div>
      <TrendPane class="trend-pane" :data="trendData"></TrendPane>
      <ChargeRanking
        ref="chargeRanking"
        :range="tabsTopActiveName"
        :dataType="tabsBottomActiveName"
        @changeTab="changeChargeRankingTab"
        :data="chargeRankingData"
      ></ChargeRanking>
    </div>
    <!-- </div> -->
  </fullscreen>
</template>

<script>
import _ from 'lodash'
import { debounce } from '@/utils'
import { loadMap, reverseGeoCode } from '@/utils/map-loaderV3'
import mapSettings from './config/mapSetting'
import getCustomOverlay from '@/utils/CustomOverlay'
import getMaskOverlay from '@/utils/mask'
import TrendPane from './components/TrendPane'
import ChargeRanking from './components/ChargeRanking'
// import screenfull from 'screenfull'
import {
  dataToday,
  trendStatistics,
  topData,
  mapData,
  areaStation,
  areaBill,
  areaAvailability,
  leftStationPlugNum,
  leftStationChargeSum,
  leftStationPlugUsage,
} from '@/api/dashboard'
import fullscreen from 'vue-fullscreen'
import Vue from 'vue'
Vue.use(fullscreen)
const whiteList = ['ADMIN', 'SELF_OPERATION_ADMIN']
const zoomRange = ['country', 'province', 'city', 'district']
const zoomLevel = {
  country: {
    min: 4,
    max: 6,
  },
  province: {
    min: 6,
    max: 10,
  },
  city: {
    min: 10,
    max: 11,
  },
  district: {
    min: 11,
    max: 13,
  },
}
const chargeRankingHander = {
  area: {
    deviceNum: {
      fn: areaStation,
      name: 'areaName',
      data: 'stationNum',
    },
    chargeSum: {
      fn: areaBill,
      name: 'areaName',
      data: 'billNum',
    },
    plugUsage: {
      fn: areaAvailability,
      name: 'areaName',
      data: 'availability',
    },
  },
  station: {
    deviceNum: {
      fn: leftStationPlugNum,
      name: 'stationName',
      data: 'amount',
    },
    chargeSum: {
      fn: leftStationChargeSum,
      name: 'stationName',
      data: 'amount',
    },
    plugUsage: {
      fn: leftStationPlugUsage,
      name: 'stationName',
      data: 'amount',
    },
  },
}
export default {
  name: 'Statistics0',
  components: { TrendPane, ChargeRanking },
  computed: {
    roleType() {
      return this.$store.getters.roleType
    },
    userStatisticsVisible() {
      return whiteList.includes(this.roleType)
    },
  },
  data() {
    return {
      maskoverlay: null,
      timeObj: {},
      zoom: 'country',
      zoomId: null,
      areaName: '全国',
      centerPoint: '全国',
      mapQueryParams: {
        zoom: 'country',
        zoomId: null,
      },
      overlayData: [],
      overlayList: [],
      loadingDashboardInfo: true,
      map: null,
      isControl: false,
      isClick: false,
      fullscreen: false,
      tabsTopActiveName: 'area',
      tabsBottomActiveName: 'deviceNum',
      timerList: [],
      leftPanelData: {
        consumeBill: {
          label: '今日充电次数',
          value: 0,
          unit: '次',
        },
        electric: {
          label: '今日充电量',
          value: 0,
          unit: 'kWh',
        },
        appUser: {
          label: '今日新增用户数',
          value: 0,
          unit: '位',
        },
        alarm: {
          label: '今日充电保护次数',
          value: 0,
          unit: '次',
        },
      },
      rightPanelData: {
        cooperativePartnerAmount: {
          label: '合作伙伴数',
          value: 0,
          unit: '家',
        },
        stationAmount: {
          label: '电站数',
          value: 0,
          unit: '个',
        },
        portAmount: {
          label: '端口数',
          value: 0,
          unit: '个',
        },
        userAmount: {
          label: '用户数',
          value: 0,
          unit: '位',
        },
      },
      trendData: {},
      chargeRankingData: [],
    }
  },
  watch: {
    overlayList(val) {
      val.forEach((item) => this.map.addOverlay(item))
    },
    deep: true,
  },
  created() {
    this._getLastTime()
    this._initPanelData()
  },
  activated() {
    let timerPanel = setInterval(this._initPanelData, 10000)
    let timerMap = setInterval(this._getMapData, 10000)
    let timerTime = setInterval(this._getLastTime, 1000)
    this.timerList = [timerPanel, timerMap, timerTime]
    if (this.map) {
      this._registMapEvents()
      this.map.addEventListener('tilesloaded', this._handleTilesloaded)
    }
  },
  deactivated() {
    window.onresize = null
    this.timerList.forEach((item) => clearInterval(item))
    this.timerList = []
    if (this.map) {
      this.map.removeEventListener('tilesloaded', this._handleTilesloaded)
      this.map.onload = null
      this.map.onzoomend = null
      this.map.ondragend = null
    }
  },
  deystroyed() {
    window.onresize = null
    this.timerList.forEach((item) => clearInterval(item))
    this.timerList = []
    if (this.map) {
      this.map.removeEventListener('tilesloaded', this._handleTilesloaded)
      this.map.onload = null
      this.map.onzoomend = null
      this.map.ondragend = null
    }
  },
  mounted() {
    this.initMap()
  },
  methods: {
    toggle() {
      this.fullscreen = !this.fullscreen
      this.centerPoint = this.map.getCenter()
    },
    _initPanelData() {
      this._getLeftData()
      this._getRightData()
      this._getTrendData()
      if (this.zoom === 'district') {
        this.tabsTopActiveName = 'station'
        this.$refs.chargeRanking.setTabsDisabled()
      }
      this._getChargeRankingData()
    },
    _initParams({ zoomId, zoom, areaName, centerPoint }) {
      this.zoomId = zoomId
      this.zoom = zoom
      this.areaName = areaName
      this.centerPoint = centerPoint
      this._initPanelData()
      this._getMapData()
    },
    _getZoomLevel() {
      if (!this.map) return
      let zoom
      let zoomNum = this.map.getZoom()
      zoom =
        (zoomNum <= zoomLevel.country.max && 'country') ||
        (zoomNum <= zoomLevel.province.max && 'province') ||
        (zoomNum <= zoomLevel.city.max && 'city') ||
        (zoomNum > zoomLevel.district.min && 'district')
      return zoom
    },
    _getMapParams() {
      return new Promise((resolve, reject) => {
        let zoom = this._getZoomLevel()
        let point = this.map.getCenter()
        reverseGeoCode(point).then(
          (res) => {
            let params = {
              zoom: zoom,
              zoomId: zoom === 'country' ? null : res.addressComponent.adcode,
            }
            resolve(params)
          },
          (error) => {
            reject(error)
          }
        )
      })
    },
    _getLastTime() {
      this.timeObj = {
        year: new Date().getFullYear(),
        date: new Date().getMonth() + 1 + '月' + new Date().getDate() + '日',
        time: new Date()
          .toLocaleString('chinese', { hour12: false })
          .split(' ')[1],
      }
    },
    _getLeftData() {
      dataToday({ zoom: this.zoom, zoomId: this.zoomId }).then((res) => {
        Object.keys(res).forEach((key) => {
          this.leftPanelData[key].value = res[key]
        })
      })
    },
    _getRightData() {
      topData({ zoom: this.zoom, zoomId: this.zoomId }).then((res) => {
        Object.keys(res).forEach((key) => {
          this.rightPanelData[key].value = res[key]
        })
      })
    },
    _getTrendData() {
      trendStatistics({ zoom: this.zoom, zoomId: this.zoomId }).then((res) => {
        this.trendData = res
      })
    },
    _getChargeRankingData() {
      const interfaceName =
        chargeRankingHander[this.tabsTopActiveName][this.tabsBottomActiveName]
      interfaceName.fn({ zoom: this.zoom, zoomId: this.zoomId }).then((res) => {
        let data = []
        res.forEach((item) => {
          data.push({
            label: item[interfaceName.name],
            data: item[interfaceName.data],
          })
        })
        this.chargeRankingData = data
      })
    },
    changeChargeRankingTab(params) {
      this.tabsTopActiveName = params.tabsTopActiveName
      this.tabsBottomActiveName = params.tabsBottomActiveName
      this._getChargeRankingData()
    },
    _getMapData() {
      mapData(this.mapQueryParams).then((res) => {
        this.loadingDashboardInfo = false
        if (_.isEqual(this.overlayData, res)) return
        this.overlayData = res
        this._createOverlay()
      })
    },
    _createOverlay() {
      if (!this.map) return
      this.overlayList.forEach((item) => this.map.removeOverlay(item))
      let CustomOverlay = getCustomOverlay()
      this.overlayList = []
      this.overlayData.forEach((item) => {
        let myGeo = new window.BMapGL.Geocoder()
        let index = zoomRange.findIndex(
          (item) => item === this.mapQueryParams.zoom
        )
        let indexNext = index === zoomRange.length - 1 ? index : index + 1
        let zoomNext = zoomRange[indexNext]
        let address = zoomRange
          .slice(1, indexNext + 1)
          .map((key) => item[key])
          .join('')
        if (index === zoomRange.length - 1) {
          let label = new window.BMapGL.Label(
            item.stationName + '，端口数:' + item.plugNum,
            {
              position: new window.BMapGL.Point(
                item.stationLng,
                item.stationLat
              ),
            }
          )
          let style = {
            color: '#fff',
            fontSize: '12px',
            padding: '5px',
            backgroundColor: '#649C00',
            border: '0',
            borderRadius: '10px',
          }
          let hoverStyle = {
            backgroundColor: 'orange',
            zIndex: 99999,
          }
          let normalStyle = {
            backgroundColor: '#649C00',
            zIndex: 1,
          }
          label.setStyle(style)
          label.addEventListener('mouseout', () => {
            label.setStyle(normalStyle)
          })
          label.addEventListener('mouseover', () => {
            label.setStyle(hoverStyle)
          })
          this.overlayList.push(label)
        } else {
          myGeo.getPoint(
            address,
            (point) => {
              if (point) {
                let clickCallback = () => {
                  this.isClick = true
                  this.map.centerAndZoom(point, zoomLevel[zoomNext].min + 1)
                  this.mapQueryParams = {
                    zoom: zoomNext,
                    zoomId: item.areaCode,
                  }
                  this._initParams({
                    zoomId: item.areaId,
                    zoom: zoomNext,
                    areaName: address,
                    centerPoint: this.centerPoint,
                  })
                }
                let mySquare = new CustomOverlay(
                  point,
                  item[zoomNext],
                  item,
                  clickCallback,
                  'pointOverlay'
                )
                this.overlayList.push(mySquare)
              }
            },
            item[zoomNext]
          )
        }
      })
    },
    _registMapEvents() {
      if (!this.map) return
      window.onresize = () => {
        this.map.setCenter(this.centerPoint)
      }
      this.map.onload = () => {
        this.isControl = false
      }
      this.map.ondragend = debounce(async () => {
        if (!this.isControl) return
        this.mapQueryParams = await this._getMapParams()
        this._getMapData()
      })

      this.map.onzoomend = debounce(async () => {
        if (!this.isControl) return
        if (this.isClick) {
          this.isClick = false
          return
        }

        this.mapQueryParams = await this._getMapParams()
        this.mapQueryParams.zoom === 'country' &&
          this.$refs.chargeRanking.clearTabsDisabled()
        this.mapQueryParams.zoom === 'country'
          ? this._initParams({
              zoomId: null,
              zoom: 'country',
              areaName: '全国',
              centerPoint: '全国',
            })
          : this._getMapData()
      })
    },
    _handleTilesloaded() {
      this.isControl = true
      this.maskoverlay._div.style.background =
        'radial-gradient(circle at center,transparent,rgba(12,13,15,0.1),rgba(12,13,15,0.3),rgba(12,13,15,0.7),#0c0d0f 68%)'
    },
    _createMask() {
      let Maskoverlay = getMaskOverlay()
      this.maskoverlay = new Maskoverlay('全国', 'mask')
      this.map.addOverlay(this.maskoverlay)
      this.map.addEventListener('tilesloaded', this._handleTilesloaded)
    },
    initMap() {
      loadMap().then(() => {
        let mapOptions = {
          minZoom: 5,
          maxZoom: 19,
          enableMapClick: false,
        }
        this.map = new window.BMapGL.Map('preview-map', mapOptions)
        this.map.setMapStyleV2({
          styleJson: mapSettings,
        })
        this.map.centerAndZoom('中国')
        this.map.enableScrollWheelZoom(true)
        this.map.disableDoubleClickZoom()
        this.map.enableAutoResize()
        this._createMask()
        this._registMapEvents()
        this._getMapData()
      })
    },
  },
}
</script>
<style lang="scss" scoped>
.container {
  height: 100%;
  width: 100%;
  position: relative;
  background: #0c0d0f;
}
.btn {
  position: absolute;
  left: 15px;
  bottom: 15px;
  z-index: 9999;
  cursor: pointer;
  height: 40px;
  width: 40px;
}
.screen {
  background: url('../../assets/images/exhibition/fullscreen.png') center
    no-repeat;
  background-size: cover;
  &:hover {
    background-image: url('../../assets/images/exhibition/fullscreenlight.png');
  }
}
.back {
  background: url('../../assets/images/exhibition/back.png') center no-repeat;
  background-size: cover;
  &:hover {
    background-image: url('../../assets/images/exhibition/backlight.png');
  }
}
.header {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  z-index: 999;
  display: flex;
  justify-content: space-between;
  .left-header {
    img:first-child {
      height: 56px;
      margin-left: 46px;
      margin-top: 28px;
    }
    img:last-child {
      height: 52px;
      margin-top: -52px;
      width: 100%;
      // min-width: 1200px;
    }
  }
  .right-header {
    margin-top: 41px;
    display: flex;
    align-items: center;
    color: #ffffff;
    font-size: 16px;
    img {
      height: 50px;
      margin-left: 30px;
    }

    .area {
      display: flex;
      white-space: nowrap;
      align-items: center;
      &::after {
        content: '';
        display: inline-block;
        background: #087bff;
        height: 46px;
        width: 4px;
        margin: 0 16px;
      }
    }
    .time {
      color: #ffffff;
      font-size: 12px;
      font-family: Helvetica;
      font-style: oblique;
      & > div {
        white-space: nowrap;
        &:nth-of-type(1) {
          font-weight: 800;
          margin-bottom: 5px;
        }
        &:nth-of-type(2) {
          font-weight: 800;
          font-size: 16px;
          margin-bottom: -5px;
        }
      }
    }
  }
}
.preview-map-container {
  width: 71%;
  min-height: 100%;
  background: #0c0d0f !important;
  position: absolute;
  background-image: none !important;
  overflow: hidden;
}
.left-panel {
  position: absolute;
  top: 30%;
  left: 40px;
  overflow-y: auto;
  color: #bebbbf;
  z-index: 9999;
  font-size: 14px;
  .left-panel-item {
    margin-bottom: 42px;
  }
  .left-panel-value {
    font-size: 28px;
    color: #e0e0e0;
    margin-right: 5px;
    font-weight: 800;
    font-style: oblique;
    margin-top: 15px;
    font-family: Helvetica;
  }
}
.right-panel {
  position: absolute;
  top: 15%;
  bottom: 20px;
  width: 45%;
  right: 50px;
  color: #bebbbf;
  z-index: 9999;
  font-size: 16px;
  .right-panel-number {
    display: flex;
    width: 100%;
    justify-content: space-between;
    .right-panel-value {
      font-size: 28px;
      color: #e0e0e0;
      margin-right: 15px;
      font-weight: 800;
      font-style: oblique;
      margin-top: 15px;
      font-family: Helvetica;
      vertical-align: center;
    }
  }
}
</style>
